package com.andrewchatham.pony;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.SQLException;
import android.util.Log;

import com.andrewchatham.SynctasticProto.PlaylistNames;

class PlaylistDB extends DB {
	private static final String TAG = "PlaylistDB";
	private static final String DATABASE_TABLE = "playlists";
	private static final int DATABASE_VERSION = 3;
	public static final String KEY_NAME = "_id";
	public static final String KEY_SYNC = "sync";
	private static final String DATABASE_CREATE =
		"create table playlists (_id string primary key, sync boolean);";

	public PlaylistDB(Context ctx) {
		super(ctx, DATABASE_TABLE, DATABASE_VERSION, DATABASE_CREATE);
	}

	public Cursor fetchAll() {
		Cursor c = mDB.query(DATABASE_TABLE, new String[] {KEY_NAME, KEY_SYNC},
				null, null, null, null, null);
		if (c != null)
			c.moveToFirst();
		return c;
	}

	private String listWhereClause(String playlist) {
		return KEY_NAME + "=" + DatabaseUtils.sqlEscapeString(playlist);
	}

	public boolean listExists(String playlist) throws SQLException {
		Cursor cursor =
			mDB.query(true, DATABASE_TABLE, new String[] {KEY_NAME},
					listWhereClause(playlist), 
					null, null, null, null, null);
		boolean ret = cursor.getCount() > 0;
		cursor.close();
		return ret;
	}

	public void setSync(String playlist, boolean sync) {
		ContentValues values = new ContentValues();
		values.put(KEY_SYNC, sync ? 1 : 0);
		mDB.update(DATABASE_TABLE, values, listWhereClause(playlist), null);
	}

	private void insertListIfNew(String playlist) {
		if (listExists(playlist))
			return;
		ContentValues values = new ContentValues();
		values.put(KEY_NAME, playlist);
		values.put(KEY_SYNC, 0);
		mDB.insert(DATABASE_TABLE, null, values);
		Log.d(TAG, "Inserting " + playlist);
	}

	/**
	 * Get the list of playlist names to be synced.
	 * 
	 * @return List of playlist names to be synced
	 */
	public ArrayList<String> getSyncPlaylists() {
		Cursor c = mDB.query(DATABASE_TABLE, new String[] {KEY_NAME, KEY_SYNC},
				null, null, null, null, null);
		ArrayList<String> ret = new ArrayList<String>();
		for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
			if (c.getInt(1) != 0)
				ret.add(c.getString(0));
		}
		c.close();
		return ret;
	}

	/**
	 * Update the database to have only the playslists given. Any existing sync preferences will be preserved, and new playlists will be unsynced.
	 * 
	 * @param playlists
	 */
	public void setPlaylists(PlaylistNames playlists) {
		Set<String> playlistSet = new HashSet<String>();
		for (String playlist : playlists.getPlaylistList()) {
			playlistSet.add(playlist);
			insertListIfNew(playlist);
		}

		// Remove any playlists which were not passed in.
		Cursor c = mDB.query(DATABASE_TABLE, new String[] {KEY_NAME},
				null, null, null, null, null);
		for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
			String name = c.getString(0);
			if (!playlistSet.contains(name))
				deleteList(name);
		}
		c.close();
	}

	/**
	 * Remove the given playlist from the database.
	 * 
	 * @param playlist
	 */
	private void deleteList(String playlist) {
		mDB.delete(DATABASE_TABLE, listWhereClause(playlist), null);	
	}
}
